home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / msdos / raytrace / pov / bin / xtras / povray.c < prev    next >
C/C++ Source or Header  |  1994-09-11  |  37KB  |  1,235 lines

  1. /****************************************************************************
  2. *
  3. *  ATTENTION!!!
  4. *
  5. *  THIS FILE HAS BEEN MODIFIED!!! IT IS NOT PART OF THE OFFICAL
  6. *  POV-RAY 2.2 DISTRIBUTION!!!
  7. *
  8. *  THIS FILE IS PART OF "FASTER THAN POV-RAY" (VERSION 2.2),
  9. *  A SPED-UP VERSION OF POV-RAY 2.2. USE AT YOUR OWN RISK!!!!!!
  10. *
  11. *  New files: addon0.c, addon1.c, addon2.c, addon3.c, addon.h
  12. *
  13. *  The additional modules were written by Dieter Bayer.
  14. *
  15. *  Send comments, suggestions, bugs, ideas ... to:
  16. *
  17. *  e-mail: dieter@cip.e-technik.uni-erlangen.de
  18. *  CIS: 100255.3074
  19. *
  20. *  All changed/added lines are enclosed in #ifdef DB_CODE ... #endif
  21. *
  22. *  The vista projection was taken from:
  23. *
  24. *    A. Hashimoto, T. Akimoto, K. Mase, and Y. Suenaga, 
  25. *    "Vista Ray-Tracing: High Speed Ray Tracing Using Perspective
  26. *    Projection Image", New Advances in Computer Graphics, Proceedings
  27. *    of CG International '89, R. A. Earnshaw, B. Wyvill (Eds.), 
  28. *    Springer, ..., pp. 549-560
  29. *
  30. *  The idea for the light buffer was taken from:
  31. *
  32. *    E. Haines and D. Greenberg, "The Light Buffer: A Shadow-Testing 
  33. *    Accelerator", IEEE CG&A, Vol. 6, No. 9, Sept. 1986, pp. 6-16
  34. *
  35. *****************************************************************************/
  36.  
  37. /****************************************************************************
  38. *                povray.c
  39. *
  40. *  This module contains the entry routine for the raytracer and the code to
  41. *  parse the parameters on the command line.
  42. *
  43. *  from Persistence of Vision Raytracer
  44. *  Copyright 1993 Persistence of Vision Team
  45. *---------------------------------------------------------------------------
  46. *  NOTICE: This source code file is provided so that users may experiment
  47. *  with enhancements to POV-Ray and to port the software to platforms other 
  48. *  than those supported by the POV-Ray Team.  There are strict rules under
  49. *  which you are permitted to use this file.  The rules are in the file
  50. *  named POVLEGAL.DOC which should be distributed with this file. If 
  51. *  POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  52. *  Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  53. *  Forum.  The latest version of POV-Ray may be found there as well.
  54. *
  55. * This program is based on the popular DKB raytracer version 2.12.
  56. * DKBTrace was originally written by David K. Buck.
  57. * DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  58. *
  59. *****************************************************************************/
  60.  
  61. #include <ctype.h>
  62. #include <time.h>          /* BP */
  63. #include "frame.h"        /* common to ALL modules in this program */
  64. #include "povproto.h"
  65. #ifdef DB_CODE
  66. #include "addon.h"
  67. #endif
  68.  
  69. #define MAX_FILE_NAMES 1
  70. unsigned int Options;
  71. unsigned long Quality_Flags;
  72. int Quality,Use_Slabs;
  73. int Case_Sensitive_Flag = CASE_SENSITIVE_DEFAULT;
  74.  
  75. #ifdef DB_CODE
  76. extern unsigned long nChecked, nEnqueued;
  77. extern unsigned long Project_Tests, Project_Tests_Succeeded;
  78. extern unsigned Extended_Options, Project_Algorithm;
  79. #endif
  80. extern FRAME Frame;
  81. OBJECT *Root_Object;
  82.  
  83. char Input_File_Name[FILE_NAME_LENGTH], Output_File_Name[FILE_NAME_LENGTH], Stat_File_Name[FILE_NAME_LENGTH];
  84.  
  85. #define MAX_LIBRARIES 10
  86. char *Library_Paths[MAX_LIBRARIES];
  87. int Library_Path_Index;
  88. int Max_Symbols = 1000;
  89.  
  90. FILE_HANDLE *Output_File_Handle;
  91. int File_Buffer_Size;
  92. static int Number_Of_Files;
  93. static int inflag, outflag; 
  94. DBL VTemp;
  95. DBL Antialias_Threshold;
  96. int First_Line, Last_Line;
  97. int First_Column, Last_Column;
  98. DBL First_Column_Temp, Last_Column_Temp;
  99. DBL First_Line_Temp, Last_Line_Temp;
  100. int Display_Started = FALSE;
  101. int Shadow_Test_Flag = FALSE;
  102. DBL Clock_Value = 0.0;
  103. DBL Language_Version = 2.0;
  104. long Bounds_Threshold = 25;
  105. long AntialiasDepth = 3;
  106. DBL JitterScale = 1.0;
  107.  
  108. /* Quality constants */
  109.   long Quality_Values[10]=
  110.     {
  111.     QUALITY_0, QUALITY_1, QUALITY_2, QUALITY_3, QUALITY_4,
  112.     QUALITY_5, QUALITY_6, QUALITY_7, QUALITY_8, QUALITY_9
  113.     };
  114. /* Stats kept by the ray tracer: */
  115. long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  116. long Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded;
  117. long Ray_Box_Tests, Ray_Box_Tests_Succeeded;    
  118. long Ray_Blob_Tests, Ray_Blob_Tests_Succeeded;  
  119. long Ray_Cone_Tests, Ray_Cone_Tests_Succeeded;
  120. long Ray_Disc_Tests, Ray_Disc_Tests_Succeeded;
  121. long Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
  122. long Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
  123. long Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
  124. long Ray_Poly_Tests, Ray_Poly_Tests_Succeeded;
  125. long Ray_Bicubic_Tests, Ray_Bicubic_Tests_Succeeded;
  126. long Ray_Ht_Field_Tests, Ray_Ht_Field_Tests_Succeeded;
  127. long Ray_Ht_Field_Box_Tests, Ray_HField_Box_Tests_Succeeded;
  128. long Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
  129. long Clipping_Region_Tests, Clipping_Region_Tests_Succeeded;
  130. long Calls_To_Noise, Calls_To_DNoise;
  131. /* SJA */
  132. long Shadow_Ray_Tests, Shadow_Rays_Succeeded, Shadow_Cache_Hits;
  133. /* SJA */
  134. long Reflected_Rays_Traced, Refracted_Rays_Traced;
  135. long Transmitted_Rays_Traced;
  136. long Istack_overflows;
  137. int Number_of_istacks;
  138. int Max_Intersections;
  139. ISTACK *free_istack;
  140.  
  141. DBL    tused;             /* Trace timer variables. - BP */
  142. time_t tstart, tstop;
  143.  
  144. char DisplayFormat, OutputFormat, VerboseFormat, PaletteOption, Color_Bits;
  145.  
  146. struct Constant_Struct Constants[MAX_CONSTANTS];
  147.  
  148. #ifdef NOCMDLINE    /* a main() by any other name... */
  149. #ifdef ALTMAIN
  150.   MAIN_RETURN_TYPE alt_main()
  151. #else
  152.   MAIN_RETURN_TYPE main()
  153. #endif
  154. #else
  155. #ifdef ALTMAIN
  156.   MAIN_RETURN_TYPE alt_main(argc, argv)
  157. #else
  158.   MAIN_RETURN_TYPE main(argc, argv)
  159. #endif
  160.     int argc;
  161. char **argv;
  162. #endif            /* ...would be a lot less hassle!! :-) AAC */
  163.   {
  164.   register int i;
  165.   FILE *stat_file;
  166.  
  167.   STARTUP_POVRAY
  168.  
  169.   PRINT_CREDITS
  170.  
  171.   PRINT_OTHER_CREDITS
  172.  
  173.   /* Parse the command line parameters */
  174. #ifndef NOCMDLINE
  175.   if (argc == 1)
  176.     usage();
  177. #endif
  178.  
  179.   init_vars();
  180.  
  181.   Output_File_Name[0]='\0';
  182.  
  183.   Library_Paths[0] = NULL;
  184.   Library_Path_Index = 0;
  185.  
  186.   /* Read the default parameters from povray.def */
  187.   get_defaults();
  188.  
  189. #ifndef NOCMDLINE
  190.   for (i = 1 ; i < argc ; i++ )
  191.     if ((*argv[i] == '+') || (*argv[i] == '-'))
  192.       parse_option(argv[i]);
  193.     else
  194.       parse_file_name(argv[i]);
  195.  
  196. #endif
  197.  
  198.   if (Last_Line == -1)
  199.     Last_Line = Frame.Screen_Height;
  200.  
  201.   if (Last_Column == -1)
  202.     Last_Column = Frame.Screen_Width;
  203.  
  204.   if (Options & DISKWRITE) 
  205.     {
  206.     switch (OutputFormat) 
  207.     {
  208.     case '\0':
  209.     case 'd':
  210.     case 'D':
  211.       if ((Output_File_Handle = Get_Dump_File_Handle()) == NULL) 
  212.         {
  213.         close_all();
  214.         exit(1);
  215.         }
  216.       break;
  217.       /*
  218.          case 'i':
  219.          case 'I':
  220.                    if ((Output_File_Handle = Get_Iff_File_Handle()) == NULL) {
  221.                       close_all();
  222.                       exit(1);
  223.                       }
  224.                    break;
  225.  
  226. */
  227.     case 'r':
  228.     case 'R':
  229.       if ((Output_File_Handle = Get_Raw_File_Handle()) == NULL)
  230.         {
  231.         close_all();
  232.         exit(1);
  233.         }
  234.       break;
  235.  
  236.     case 't':
  237.     case 'T':
  238.       if ((Output_File_Handle = Get_Targa_File_Handle()) == NULL) 
  239.     {
  240.         close_all();
  241.         exit(1);
  242.     }
  243.       break;
  244.  
  245.     default:
  246.       fprintf (stderr, "Unrecognized output file format %c\n", OutputFormat);
  247.       close_all(); 
  248.       exit(1);
  249.     }
  250.     if (Output_File_Name[0] == '\0')
  251.       strcpy (Output_File_Name, Default_File_Name (Output_File_Handle));
  252.     }
  253.  
  254.   Print_Options();
  255.  
  256.   Initialize_Tokenizer(Input_File_Name);
  257.   fprintf (stderr,"Parsing...");
  258.  
  259.  
  260.   if (Options & VERBOSE_FILE)
  261.     {
  262.     stat_file = fopen(Stat_File_Name,"w+t");
  263.     fprintf (stat_file, "Parsing...\n");
  264.     fclose(stat_file);
  265.     }
  266.  
  267.   Parse ();
  268.   Terminate_Tokenizer();
  269.  
  270. #ifdef DB_CODE
  271.   /* Init additional stuff BEFORE the bounding slabs are build. */
  272.  
  273.   Init_Additionals_1();
  274. #endif
  275.  
  276.   if (Use_Slabs)
  277.     {
  278.     fprintf (stderr, "Preprocessing...\n");  /* Added */
  279.     BuildBoundingSlabs(&Root_Object);        /* Added */
  280.     }
  281.  
  282. #ifdef DB_CODE
  283.   /* Init additional stuff AFTER the bounding slabs are build. */
  284.  
  285.   Init_Additionals_2();
  286. #endif
  287.  
  288.   if (Options & DISPLAY)
  289.     {
  290.     printf ("Displaying...\n");
  291.     display_init(Frame.Screen_Width, Frame.Screen_Height);
  292.     Display_Started = TRUE;
  293.     }
  294.  
  295. #ifdef DB_CODE
  296.   /* Draw rectangles around the projected objects */
  297.  
  298.   if ((Options & DISPLAY) && (Extended_Options & USE_PREVIEW))
  299.   {
  300.     Draw_Vista_Tree();
  301.   }
  302. #endif
  303.  
  304.   /* Get things ready for ray tracing */
  305.   if (Options & DISKWRITE)
  306.     if (Options & CONTINUE_TRACE)
  307.     {
  308.     if (Open_File (Output_File_Handle, Output_File_Name,
  309.       &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  310.       READ_MODE) != 1)
  311.       {
  312.       fprintf (stderr, "Error opening continue trace output file\n");
  313.       fprintf (stderr, "Opening new output file %s.\n",Output_File_Name);
  314.       Options &= ~CONTINUE_TRACE; /* Turn off continue trace */
  315.  
  316.       if (Open_File (Output_File_Handle, Output_File_Name,
  317.     &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  318.     WRITE_MODE) != 1)
  319.     {
  320.     fprintf (stderr, "Error opening output file\n");
  321.     close_all();
  322.     exit(1);
  323.     }
  324.       }
  325.  
  326.     Initialize_Renderer();
  327.     if (Options & CONTINUE_TRACE)
  328.       Read_Rendered_Part();
  329.     }
  330.     else
  331.     {
  332.     if (Open_File (Output_File_Handle, Output_File_Name,
  333.       &Frame.Screen_Width, &Frame.Screen_Height, File_Buffer_Size,
  334.       WRITE_MODE) != 1)
  335.       {
  336.       fprintf (stderr, "Error opening output file\n");
  337.       close_all();
  338.       exit(1);
  339.       }
  340.  
  341.     Initialize_Renderer();
  342.     }
  343.   else
  344.     Initialize_Renderer();
  345.  
  346.   Initialize_Noise();
  347.  
  348.   START_TIME  /* Store start time for trace. Timer macro in CONFIG.H */
  349.  
  350.  
  351.   /* Ok, go for it - trace the picture */
  352.   if ((Options & VERBOSE) && (VerboseFormat !='1'))
  353.     printf ("Rendering...\n");
  354.   else if ((Options & VERBOSE) && (VerboseFormat=='1'))
  355.     fprintf (stderr,"POV-Ray rendering %s to %s :\n",Input_File_Name,Output_File_Name);
  356.   if (Options & VERBOSE_FILE)
  357.     {
  358.     stat_file = fopen(Stat_File_Name,"w+t");
  359.     fprintf (stat_file,"Parsed ok. Now rendering %s to %s :\n",Input_File_Name,Output_File_Name);
  360.     fclose(stat_file);
  361.     }
  362.   CONFIG_MATH               /* Macro for setting up any special FP options */
  363.   Start_Tracing ();
  364.  
  365.   if (Options & VERBOSE && VerboseFormat=='1')
  366.     fprintf (stderr,"\n");
  367.  
  368.   /* Record the time so well spent... */
  369.   STOP_TIME                  /* Get trace done time. */
  370.   tused = TIME_ELAPSED       /* Calc. elapsed time. Define TIME_ELAPSED as */
  371.   /* 0 in your specific CONFIG.H if unsupported */
  372.  
  373.   /* Clean up and leave */
  374.   display_finished();
  375.  
  376.   close_all ();
  377.  
  378.   PRINT_STATS
  379.  
  380.   if (Options & VERBOSE_FILE)
  381.     {
  382.     stat_file = fopen(Stat_File_Name,"a+t");
  383.     fprintf (stat_file,"Done Tracing\n");
  384.     fclose(stat_file);
  385.     }
  386.  
  387.   FINISH_POVRAY
  388.   }
  389.  
  390. /* Print out usage error message */
  391.  
  392. void usage ()
  393.   {
  394.   fprintf (stdout,"\nUsage: POVRAY  [+/-] Option1 [+/-] Option2 ...");
  395.   fprintf (stdout,"\n  Example: +L\\povray\\include +Iscene.pov +Oscene.tga +W320 +H200");
  396.   fprintf (stdout,"\n  Example: +Iscene.pov +Oscene.tga +W160 +H200 +V -D +X ");
  397.   fprintf (stdout,"\n");
  398.   fprintf (stdout,"\n[ Paused for keypress... ]\n");
  399.   WAIT_FOR_KEYPRESS;
  400.   fprintf (stdout,"\n\n\n\n\n Options:");
  401.   fprintf (stdout,"\n    Dxy = display in format x, using palette option y");
  402.   fprintf (stdout,"\n    V   = verbose messages on");
  403.   fprintf (stdout,"\n    P  = pause before exit");
  404.   fprintf (stdout,"\n    X  = enable early exit by key hit");
  405.   fprintf (stdout,"\n    Fx = write output file in format x");
  406.   fprintf (stdout,"\n         FT - Uncompressed Targa-24  |  FD - DKB/QRT Dump  | FR - RGB Raw Files");
  407.   fprintf (stdout,"\n    C  = continue aborted trace");
  408.   fprintf (stdout,"\n    Qx = image quality 0=rough, 9=full");
  409.   fprintf (stdout,"\n    A0.x = perform antialiasing");
  410.   fprintf (stdout,"\n    Bxxx = Use xxx KB for output file buffer");
  411.   fprintf (stdout,"\n    Jx.x = set aa-jitter amount");
  412.   fprintf (stdout,"\n    Kx.x = set frame clocK to x.x");
  413.   fprintf (stdout,"\n    MBxxx = use slabs if more than xxx objects");
  414.   fprintf (stdout,"\n    MSxxx = set max symbol table size to xxx");
  415.   fprintf (stdout,"\n    MVx.x = set compability to version x.x");
  416.   fprintf (stdout,"\n    Rn   = set aa-depth (use n X n rays/pixel)");
  417.   fprintf (stdout,"\n    SRxx = start at row xxx         |  SR0.xx start row at x%% of screen");
  418.   fprintf (stdout,"\n    ERxx = end   at row xxx         |  ER0.xx end   row at x%% of screen");
  419.   fprintf (stdout,"\n    SCxx = start at col xxx         |  SC0.xx start col at x%% of screen");
  420.   fprintf (stdout,"\n    ECxx = end   at col xxx         |  EC0.xx end   col at x%% of screen");
  421.   fprintf (stdout,"\n    I<filename> = input file name   |  O<filename> = output file name");
  422.   fprintf (stdout,"\n    L<pathname> = library path prefix");
  423. #ifdef DB_CODE
  424.   /* Print the new options */
  425.  
  426.   fprintf (stdout,"\n[ Paused for keypress... ]\n");
  427.   WAIT_FOR_KEYPRESS;
  428.   fprintf (stdout,"\n Non-Standard Options:");
  429.   fprintf (stdout,"\n    UVB = use vista buffer for primary rays");
  430.   fprintf (stdout,"\n    ULB = use light buffer for shadow rays");
  431.   fprintf (stdout,"\n    USF = use splitting of CSG unions with finite children");
  432.   fprintf (stdout,"\n    USI = use splitting of all CSG unions");
  433.   fprintf (stdout,"\n    UBQ = use bounding of quadrics");
  434.   fprintf (stdout,"\n    UPV = use preview");
  435.   fprintf (stdout,"\n    UM1 = use vista/light buffer without slab-testing");
  436.   fprintf (stdout,"\n    UM2 = use vista/light with leaf slab-testing");
  437.   fprintf (stdout,"\n    UM3 = use vista/light with node slab-testing");
  438. #endif
  439.   fprintf (stdout,"\n");
  440.   exit(1);
  441.   }
  442. void init_vars()
  443.   {
  444.   Output_File_Handle = NULL;
  445.   File_Buffer_Size = 0;
  446.   Options = JITTER;
  447.   Quality_Flags = QUALITY_9;
  448.   Quality = 9;
  449.   Use_Slabs=TRUE;
  450.   Number_Of_Files = 0;
  451.   Frame.Screen_Height = 100;
  452.   Frame.Screen_Width = 100;
  453.   First_Line = 0;
  454.   Last_Line = -1;
  455.   First_Column = 0;
  456.   Last_Column = -1;
  457.  
  458.   First_Line_Temp = (DBL) First_Line+1;
  459.   Last_Line_Temp = (DBL) Last_Line;
  460.   First_Column_Temp = (DBL) First_Column+1;
  461.   Last_Column_Temp = (DBL) Last_Column;
  462.  
  463.   Color_Bits = 8;
  464.  
  465.   Number_Of_Pixels = 0L;
  466.   Number_Of_Rays = 0L;
  467.   Number_Of_Pixels_Supersampled = 0L;
  468.   Ray_Ht_Field_Tests = 0L;
  469.   Ray_Ht_Field_Tests_Succeeded = 0L;
  470.   Ray_Ht_Field_Box_Tests = 0L;
  471.   Ray_HField_Box_Tests_Succeeded = 0L;
  472.   Ray_Bicubic_Tests = 0L;
  473.   Ray_Bicubic_Tests_Succeeded = 0L;
  474.   Ray_Blob_Tests = 0L;
  475.   Ray_Blob_Tests_Succeeded = 0L;
  476.   Ray_Box_Tests = 0L;
  477.   Ray_Box_Tests_Succeeded = 0L;
  478.   Ray_Disc_Tests = 0L;
  479.   Ray_Disc_Tests_Succeeded = 0L;
  480.   Ray_Cone_Tests = 0L;
  481.   Ray_Cone_Tests_Succeeded = 0L;
  482.   Ray_Sphere_Tests = 0L;
  483.   Ray_Sphere_Tests_Succeeded = 0L;
  484.   Ray_Plane_Tests = 0L;
  485.   Ray_Plane_Tests_Succeeded = 0L;
  486.   Ray_Triangle_Tests = 0L;
  487.   Ray_Triangle_Tests_Succeeded = 0L;
  488.   Ray_Quadric_Tests = 0L;
  489.   Ray_Quadric_Tests_Succeeded = 0L;
  490.   Ray_Poly_Tests = 0L;
  491.   Ray_Poly_Tests_Succeeded = 0L;
  492.   Bounding_Region_Tests = 0L;
  493.   Bounding_Region_Tests_Succeeded = 0L;
  494.   Clipping_Region_Tests = 0L;
  495.   Clipping_Region_Tests_Succeeded = 0L;
  496.   Calls_To_Noise = 0L;
  497.   Calls_To_DNoise = 0L;
  498.   Shadow_Ray_Tests = 0L;
  499.   /* SJA */
  500.   Shadow_Cache_Hits = 0L;
  501.   /* SJA */
  502.   Shadow_Rays_Succeeded = 0L;
  503.   Reflected_Rays_Traced = 0L;
  504.   Refracted_Rays_Traced = 0L;
  505.   Transmitted_Rays_Traced = 0L;
  506.   Istack_overflows = 0L;
  507.   Number_of_istacks = 0;
  508.   free_istack = NULL;
  509.   Max_Intersections = 64; /*128*/
  510.   Antialias_Threshold = 0.3;
  511.   strcpy (Input_File_Name, "object.pov");
  512.   return;
  513.   }
  514.  
  515. /* Close all the stuff that has been opened. */
  516. void close_all ()
  517.   {
  518.   if ((Options & DISPLAY) && Display_Started)
  519.     display_close();
  520.  
  521.   if (Output_File_Handle)
  522.     Close_File (Output_File_Handle);
  523.   }
  524.  
  525. /* Read the default parameters from povray.def */
  526. void get_defaults()
  527.   {
  528.   FILE *defaults_file;
  529.   char Option_String[256], *Option_String_Ptr;
  530.   /* READ_ENV_VAR_? should be defined in config.h */
  531.   /* Only one READ_ENV_VAR_? should ever be defined. */
  532.   /* This allows some machines to read environment variable before */
  533.   /* reading povray.def and others to do it after depending on the */
  534.   /* operating system. IBM-PC is before. Default is after if not */
  535.   /* defined in config.h. CDW 2/92 */
  536.   /* Set Diskwrite as default */
  537.   Options |= DISKWRITE;
  538.   OutputFormat = DEFAULT_OUTPUT_FORMAT;
  539.  
  540.   READ_ENV_VAR_BEFORE
  541.   if ((defaults_file = Locate_File("povray.def", "r")) != NULL) 
  542.     {
  543.     while (fgets(Option_String, 256, defaults_file) != NULL)
  544.       read_options(Option_String);
  545.     fclose (defaults_file);
  546.     }
  547.   READ_ENV_VAR_AFTER
  548.   }
  549.  
  550. void read_options (Option_Line)
  551. char *Option_Line;
  552.   {
  553.   register int c, String_Index, Option_Started;
  554.   short Option_Line_Index = 0;
  555.   char Option_String[80];
  556.  
  557.   String_Index = 0;
  558.   Option_Started = FALSE;
  559.   while ((c = Option_Line[Option_Line_Index++]) != '\0')
  560.     {
  561.     if (Option_Started)
  562.       if (isspace(c))
  563.         {
  564.         Option_String[String_Index] = '\0';
  565.         parse_option (Option_String);
  566.         Option_Started = FALSE;
  567.         String_Index = 0;
  568.         }
  569.       else
  570.         Option_String[String_Index++] = (char) c;
  571.  
  572.     else /* Option_Started */
  573.       if ((c == (int) '-') || (c == (int) '+'))
  574.         {
  575.         String_Index = 0;
  576.         Option_String[String_Index++] = (char) c;
  577.     Option_Started = TRUE;
  578.         }
  579.       else
  580.         if (!isspace(c))
  581.       {
  582.           fprintf (stderr, 
  583.             "\nCommand line or .DEF error. Bad character (%c), val: %d.\n", 
  584.             (char) c, c);
  585.           exit (1);
  586.           }
  587.     }
  588.  
  589.   if (Option_Started)
  590.     {
  591.     Option_String[String_Index] = '\0';
  592.     parse_option (Option_String);
  593.     }
  594.   }
  595.  
  596. /* parse the command line parameters */
  597. void parse_option (Option_String)
  598. char *Option_String;
  599.   {
  600.   register int Add_Option;
  601.   unsigned int Option_Number;
  602.   long bounds_thresh;
  603.   DBL threshold;
  604.  
  605.   inflag = outflag = FALSE;   /* if these flags aren't immediately used, reset them on next -/+ option! */
  606.   if (*(Option_String++) == '-')
  607.     Add_Option = FALSE;
  608.   else
  609.     Add_Option = TRUE;
  610.  
  611.   Option_Number = 0;
  612.  
  613.   switch (*Option_String)
  614.   {
  615.   case 'B':
  616.   case 'b':
  617.     sscanf (&Option_String[1], "%d", &File_Buffer_Size);
  618.     File_Buffer_Size *= 1024;
  619.     if (File_Buffer_Size < BUFSIZ)   /* system default MIN */
  620.       File_Buffer_Size = BUFSIZ;
  621.     if (File_Buffer_Size > MAX_BUFSIZE)    /* unsigned short MAX */
  622.       File_Buffer_Size = MAX_BUFSIZE;
  623.     break;
  624.  
  625.   case 'C':
  626.   case 'c':  
  627.     Option_Number = CONTINUE_TRACE;
  628.     break;
  629.  
  630.   case 'D':
  631.   case 'd':  
  632.     Option_Number = DISPLAY;
  633.     DisplayFormat = '0';
  634.     PaletteOption = '3';
  635.     if (Option_String[1] != '\0')
  636.       DisplayFormat = (char)toupper(Option_String[1]);
  637.  
  638.     if (Option_String[1] != '\0' && Option_String[2] != '\0')
  639.       PaletteOption = (char)toupper(Option_String[2]);
  640.     break;
  641.  
  642.   case '@':  
  643.     Option_Number = VERBOSE_FILE;
  644.     if(Option_String[1] == '\0')
  645.       strcpy(Stat_File_Name, "POVSTAT.OUT");
  646.     else
  647.       strncpy (Stat_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  648.     break;
  649.  
  650.   case 'V':
  651.   case 'v':
  652.     Option_Number = VERBOSE;
  653.     VerboseFormat = (char)toupper(Option_String[1]);
  654.     if (VerboseFormat == '\0')
  655.       VerboseFormat = '1';
  656.     break;
  657.  
  658.   case 'W':
  659.   case 'w':  
  660.     sscanf (&Option_String[1], "%d", &Frame.Screen_Width);
  661.     break;
  662.  
  663.   case 'H':
  664.   case 'h':  
  665.     sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
  666.     break;
  667.  
  668.   case 'F':
  669.   case 'f':  
  670.     Option_Number = DISKWRITE;
  671.     if (isupper(Option_String[1]))
  672.       OutputFormat = (char)tolower(Option_String[1]);
  673.     else
  674.       OutputFormat = Option_String[1];
  675.  
  676.     /* Default the output format to the default in the config file */
  677.     if (OutputFormat == '\0')
  678.       OutputFormat = DEFAULT_OUTPUT_FORMAT;
  679.     break;
  680.  
  681.   case 'P':
  682.   case 'p':
  683.     Option_Number = PROMPTEXIT;
  684.     break;
  685.  
  686.   case 'I':
  687.   case 'i':  
  688.     if (Option_String[1] == '\0')
  689.       inflag = TRUE;
  690.     else 
  691.       strncpy (Input_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  692.     break;
  693.  
  694.   case 'O':
  695.   case 'o':  
  696.     if (Option_String[1] == '\0')
  697.       outflag = TRUE;
  698.     else
  699.       strncpy (Output_File_Name, &Option_String[1], FILE_NAME_LENGTH);
  700.     break;
  701.  
  702.   case 'A':
  703.   case 'a':  
  704.     Option_Number = ANTIALIAS;
  705.     if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
  706.       Antialias_Threshold = threshold;
  707.     break;
  708.  
  709.   case 'J':
  710.   case 'j':
  711.     Option_Number = JITTER;
  712.     if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
  713.        JitterScale = threshold;
  714.     if (JitterScale<=0.0)
  715.        Add_Option = FALSE;
  716.     break; 
  717.  
  718.   case 'R':
  719.   case 'r':  
  720.     sscanf (&Option_String[1], "%ld", &AntialiasDepth);
  721.     if (AntialiasDepth < 1)
  722.       AntialiasDepth = 1;
  723.     if (AntialiasDepth > 9)
  724.       AntialiasDepth = 9;
  725.     break;
  726.  
  727.   case 'X':
  728.   case 'x':
  729.     Option_Number = EXITENABLE;
  730.     break;
  731.  
  732.   case 'L':
  733.   case 'l':  
  734.     if (Library_Path_Index >= MAX_LIBRARIES) 
  735.       {
  736.       fprintf (stderr, "Too many library directories specified\n");
  737.       exit(1);
  738.       }
  739.     Library_Paths [Library_Path_Index] = malloc (strlen(Option_String));
  740.     if (Library_Paths [Library_Path_Index] == NULL) 
  741.       {
  742.       fprintf (stderr, "Out of memory. Cannot allocate memory for library pathname\n");
  743.       exit(1);
  744.       }
  745.     strcpy (Library_Paths [Library_Path_Index], &Option_String[1]);
  746.     Library_Path_Index++;
  747.     break;
  748.  
  749.   case 'T':
  750.   case 't':  
  751.     switch (toupper(Option_String[1]))
  752.     {
  753.     case 'Y':
  754.       Case_Sensitive_Flag = 0;
  755.       break;
  756.     case 'N':
  757.       Case_Sensitive_Flag = 1;
  758.       break;
  759.     case 'O':
  760.       Case_Sensitive_Flag = 2;
  761.       break;
  762.     default:
  763.       Case_Sensitive_Flag = 2;
  764.       break;
  765.     }  
  766.     break;
  767.  
  768.   case 'S':
  769.   case 's':  
  770.     switch (Option_String[1])
  771.     {
  772.     case 'c':
  773.     case 'C':
  774.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &First_Column_Temp);
  775.       break;
  776.  
  777.     case 'r': 
  778.     case 'R':
  779.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &First_Line_Temp);
  780.       break;
  781.  
  782.     default:
  783.       sscanf (&Option_String[1], DBL_FORMAT_STRING, &First_Line_Temp);
  784.       break;
  785.     }
  786.  
  787.     if(First_Column_Temp > 0.0 && First_Column_Temp < 1.0)
  788.       First_Column = (int) (Frame.Screen_Width * First_Column_Temp);
  789.     else
  790.       First_Column = (int) First_Column_Temp-1;
  791.  
  792.     if(First_Line_Temp > 0.0 && First_Line_Temp < 1.0)
  793.       First_Line = (int) (Frame.Screen_Height * First_Line_Temp);
  794.     else
  795.       First_Line = (int) First_Line_Temp-1;
  796.  
  797.     if (First_Column < 0)
  798.       First_Column = 0;
  799.  
  800.     if (First_Line < 0)
  801.       First_Line = 0;
  802.  
  803.     break;
  804.  
  805.   case 'E':
  806.   case 'e': 
  807.     switch (Option_String[1])
  808.     {
  809.     case 'c': 
  810.     case 'C':
  811.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &Last_Column_Temp);
  812.       break;
  813.  
  814.     case 'r': 
  815.     case 'R':
  816.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &Last_Line_Temp);
  817.       break;
  818.  
  819.     default:
  820.       sscanf (&Option_String[1], DBL_FORMAT_STRING, &Last_Line_Temp);
  821.       break;
  822.     }
  823.  
  824.     if(Last_Column_Temp > 0.0 && Last_Column_Temp < 1.0)
  825.       Last_Column = (int) (Frame.Screen_Width * Last_Column_Temp);
  826.     else
  827.       Last_Column = (int) Last_Column_Temp;
  828.  
  829.     if(Last_Line_Temp > 0.0 && Last_Line_Temp < 1.0)
  830.       Last_Line = (int) (Frame.Screen_Height * Last_Line_Temp);
  831.     else
  832.       Last_Line = (int) Last_Line_Temp;
  833.  
  834.     if (Last_Column < 0 || Last_Column > Frame.Screen_Width)
  835.       Last_Column = Frame.Screen_Width;
  836.  
  837.     if (Last_Line > Frame.Screen_Height)
  838.       Last_Line = Frame.Screen_Height;
  839.  
  840.     break;
  841.  
  842.   case 'M': /* Switch used so other max values can be inserted easily */
  843.   case 'm':  
  844.     switch (Option_String[1])
  845.     {
  846.     case 's': /* Max Symbols */
  847.     case 'S':
  848.       sscanf (&Option_String[2], "%d", &Max_Symbols);
  849.       break;
  850.     case 'v': /* Max Version */
  851.     case 'V':
  852.       sscanf (&Option_String[2], DBL_FORMAT_STRING, &Language_Version);
  853.       break;
  854.     case 'b': /* Min Bounded */
  855.     case 'B':
  856.       if (sscanf (&Option_String[2], "%ld", &bounds_thresh) != EOF)
  857.     Bounds_Threshold=bounds_thresh;
  858.       Use_Slabs = Add_Option;
  859.       break;
  860.     default:
  861.       break;
  862.     }
  863.     break;
  864.  
  865.   case 'Q':
  866.   case 'q':
  867.     sscanf (&Option_String[1], "%d", &Quality);
  868.     if ((Quality < 0) || (Quality > 9))
  869.       Error("Illegal +Q switch setting");
  870.     Quality_Flags = Quality_Values[Quality];
  871.     break;
  872.  
  873.     /* Turn on debugging print statements. */
  874.   case 'Z':
  875.   case 'z':
  876.     Option_Number = DEBUGGING;
  877.     break;
  878.  
  879.     /* +Y switch to remain undocumented.  Add to +Q later */
  880.   case 'Y':
  881.   case 'y':
  882.     Use_Slabs = Add_Option;
  883.     break;
  884.  
  885.   case 'K':
  886.   case 'k':
  887.     sscanf (&Option_String[1], DBL_FORMAT_STRING, &Clock_Value);
  888.     break;
  889.  
  890. #ifdef DB_CODE
  891.   /* Get new options */
  892.  
  893.   case 'U':
  894.   case 'u':
  895.     if (((Option_String[1] == 'L') || (Option_String[1] == 'l')) &&
  896.     ((Option_String[2] == 'B') || (Option_String[2] == 'b')))
  897.     {
  898.       Option_Number = USE_LIGHT_BUFFER;
  899.     }
  900.     if (((Option_String[1] == 'V') || (Option_String[1] == 'v')) &&
  901.     ((Option_String[2] == 'B') || (Option_String[2] == 'b')))
  902.     {
  903.       Option_Number = USE_VISTA_BUFFER;
  904.     }
  905.     if (((Option_String[1] == 'S') || (Option_String[1] == 's')) &&
  906.     ((Option_String[2] == 'F') || (Option_String[2] == 'f')))
  907.     {
  908.       Option_Number = USE_SPLIT_FINITE_UNIONS;
  909.     }
  910.     if (((Option_String[1] == 'S') || (Option_String[1] == 's')) &&
  911.     ((Option_String[2] == 'I') || (Option_String[2] == 'i')))
  912.     {
  913.       Option_Number = USE_SPLIT_INFINITE_UNIONS;
  914.     }
  915.     if (((Option_String[1] == 'B') || (Option_String[1] == 'b')) &&
  916.     ((Option_String[2] == 'Q') || (Option_String[2] == 'q')))
  917.     {
  918.       Option_Number = USE_BOUND_QUADRICS;
  919.     }
  920.     if (((Option_String[1] == 'P') || (Option_String[1] == 'p')) &&
  921.     ((Option_String[2] == 'V') || (Option_String[2] == 'v')))
  922.     {
  923.       Option_Number = USE_PREVIEW;
  924.     }
  925.     if ((Option_String[1] == 'M') || (Option_String[1] == 'm'))
  926.     {
  927.       switch (Option_String[2])
  928.       {
  929.     case '1' : Project_Algorithm = PROJECTIONS_WITHOUT_SLABS;
  930.            break;
  931.     case '2' : Project_Algorithm = PROJECTIONS_WITH_LEAF_SLABS;
  932.            break;
  933.     case '3' : Project_Algorithm = PROJECTIONS_WITH_NODE_SLABS;
  934.            break;
  935.     default  : Project_Algorithm = PROJECTIONS_WITH_LEAF_SLABS;
  936.            fprintf(stderr, "\nUnknown tree-descending-method: %c\n\n", Option_String[2]);
  937.       }
  938.     }
  939.     if (Option_Number != 0)
  940.     {
  941.       if (Add_Option)
  942.     Extended_Options |= Option_Number;
  943.       else
  944.     Extended_Options &= ~Option_Number;
  945.     }
  946.     Option_Number = 0;
  947.     break;
  948. #endif
  949.  
  950.   default:
  951.     fprintf (stderr, "\nInvalid option: %s\n\n", --Option_String);
  952.   }
  953.  
  954.   if (Option_Number != 0)
  955.     if (Add_Option)
  956.       Options |= Option_Number;
  957.     else Options &= ~Option_Number;
  958.   }
  959.  
  960.   void Print_Options()
  961.     {
  962.     int i;
  963.  
  964.     fprintf (stdout,"\nPOV-Ray Options in effect: ");
  965.  
  966. #ifdef DB_CODE
  967.     /* print new options used */
  968.  
  969.     if (Extended_Options & USE_VISTA_BUFFER)
  970.       fprintf(stdout, "+uvb ");
  971.  
  972.     if (Extended_Options & USE_LIGHT_BUFFER)
  973.       fprintf(stdout, "+ulb ");
  974.  
  975.     if (Extended_Options & USE_SPLIT_FINITE_UNIONS)
  976.       fprintf(stdout, "+usf ");
  977.  
  978.     if (Extended_Options & USE_SPLIT_INFINITE_UNIONS)
  979.       fprintf(stdout, "+usi ");
  980.  
  981.     if (Extended_Options & USE_BOUND_QUADRICS)
  982.       fprintf(stdout, "+ubq ");
  983.  
  984.     if (Extended_Options & USE_PREVIEW)
  985.       fprintf(stdout, "+upv ");
  986.  
  987.     if (Project_Algorithm)
  988.       fprintf(stdout, "-um%d ", Project_Algorithm);
  989. #endif
  990.  
  991.     if (Options & CONTINUE_TRACE)
  992.       fprintf (stdout,"+c ");
  993.  
  994.     if (Options & DISPLAY)
  995.       fprintf (stdout,"+d%c%c ", DisplayFormat, PaletteOption);
  996.  
  997.     if (Options & VERBOSE)
  998.       fprintf (stdout,"+v%c ", VerboseFormat);
  999.  
  1000.     if (Options & VERBOSE_FILE)
  1001.       fprintf (stdout,"+@%s ", Stat_File_Name);
  1002.  
  1003.     if (Options & DISKWRITE)
  1004.       fprintf (stdout,"+f%c ", OutputFormat);
  1005.  
  1006.     if (Options & PROMPTEXIT)
  1007.       fprintf (stdout,"+p ");
  1008.  
  1009.     if (Options & EXITENABLE)
  1010.       fprintf (stdout,"+x ");
  1011.  
  1012.     if (Use_Slabs)
  1013.       fprintf (stdout,"+mb%d ", Bounds_Threshold);
  1014.     else
  1015.       fprintf (stdout,"-mb ");
  1016.  
  1017.     if (Options & DEBUGGING)
  1018.       fprintf (stdout,"+z ");
  1019.  
  1020.     if (File_Buffer_Size != 0)
  1021.       fprintf (stdout,"-b%d ", File_Buffer_Size/1024);
  1022.  
  1023.     if (Options & ANTIALIAS)
  1024.       {
  1025.       fprintf (stdout,"+a%.3f ", Antialias_Threshold);
  1026.       if (Options & JITTER)
  1027.         fprintf (stdout,"+j%.3f ", JitterScale);
  1028.       fprintf (stdout,"+r%ld ",AntialiasDepth);
  1029.       }
  1030.  
  1031.     /* quality flags rewrite in progress by CEY */
  1032.  
  1033.     fprintf (stdout,"-q%d -w%d -h%d -s%d -e%d\n",Quality,
  1034.       Frame.Screen_Width, Frame.Screen_Height, First_Line+1, Last_Line);
  1035.  
  1036.     fprintf (stdout, "-k%.3f -mv%.1f -i%s ", Clock_Value, Language_Version,
  1037.       Input_File_Name);
  1038.  
  1039.     if (Options & DISKWRITE)
  1040.       fprintf (stdout,"-o%s ", Output_File_Name);
  1041.  
  1042.     for (i = 0 ; i < Library_Path_Index ; i++)
  1043.       fprintf (stdout,"-l%s ", Library_Paths[i]);
  1044.  
  1045.     fprintf (stdout,"\n");
  1046.     }
  1047.  
  1048. void parse_file_name (File_Name)
  1049. char *File_Name;
  1050.   {
  1051.   FILE *defaults_file;
  1052.   char Option_String[256];
  1053.  
  1054.   if (inflag)   /* file names may now be separated by spaces from cmdline option */
  1055.     {
  1056.     strncpy (Input_File_Name, File_Name, FILE_NAME_LENGTH);
  1057.     inflag = FALSE;
  1058.     return;
  1059.     }
  1060.  
  1061.   if (outflag)  /* file names may now be separated by spaces from cmdline option */
  1062.     {
  1063.     strncpy (Output_File_Name, File_Name, FILE_NAME_LENGTH);
  1064.     outflag = FALSE;
  1065.     return;
  1066.     }
  1067.  
  1068.  
  1069.   if (++Number_Of_Files > MAX_FILE_NAMES)
  1070.     {
  1071.     fprintf (stderr, "\nOnly %d option file names are allowed in a command line.",
  1072.       MAX_FILE_NAMES);
  1073.     exit(1);
  1074.     }
  1075.  
  1076.   if ((defaults_file = Locate_File(File_Name, "r")) != NULL) 
  1077.     {
  1078.     while (fgets(Option_String, 256, defaults_file) != NULL)
  1079.       read_options(Option_String);
  1080.     fclose (defaults_file);
  1081.     }
  1082.   else
  1083.     printf("\nError opening option file %s.",File_Name);  
  1084.   }
  1085.  
  1086. void print_stats()
  1087.   {
  1088.   long hours,min;
  1089.   DBL sec;
  1090.   FILE *stat_out;
  1091.   long Pixels_In_Image;
  1092.  
  1093.   if (Options & VERBOSE_FILE)
  1094.     stat_out = fopen(Stat_File_Name,"w+t");
  1095.   else
  1096.     stat_out = stdout;  
  1097.  
  1098.   Pixels_In_Image = (long)Frame.Screen_Width * (long)Frame.Screen_Height;
  1099.  
  1100.  
  1101.   fprintf (stat_out,"\n%s statistics\n",Input_File_Name);
  1102.   if(Pixels_In_Image > Number_Of_Pixels)
  1103.     fprintf (stat_out,"  Partial Image Rendered");
  1104.  
  1105.   fprintf (stat_out,"--------------------------------------\n");
  1106.   fprintf (stat_out,"Resolution %d x %d\n",Frame.Screen_Width, Frame.Screen_Height);
  1107.   fprintf (stat_out,"# Rays:  %10ld    # Pixels:  %10ld  # Pixels supersampled: %10ld\n",
  1108.     Number_Of_Rays, Number_Of_Pixels, Number_Of_Pixels_Supersampled);
  1109.  
  1110.   fprintf (stat_out,"  Ray->Shape Intersection Tests:\n");
  1111.   fprintf (stat_out,"   Type             Tests    Succeeded   Percentage\n");
  1112.   fprintf (stat_out,"  -----------------------------------------------------------\n");
  1113.   if(Ray_Sphere_Tests)
  1114.     fprintf (stat_out,"  Sphere       %10ld  %10ld  %10.2f\n", Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded, ( ((DBL)Ray_Sphere_Tests_Succeeded/(DBL)Ray_Sphere_Tests) *100.0 ) );
  1115.   if(Ray_Plane_Tests)
  1116.     fprintf (stat_out,"  Plane        %10ld  %10ld  %10.2f\n", Ray_Plane_Tests, Ray_Plane_Tests_Succeeded, ( ((DBL)Ray_Plane_Tests_Succeeded/(DBL)Ray_Plane_Tests) *100.0 ));
  1117.   if(Ray_Triangle_Tests)
  1118.     fprintf (stat_out,"  Triangle     %10ld  %10ld  %10.2f\n", Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded, ( ((DBL)Ray_Triangle_Tests_Succeeded/(DBL)Ray_Triangle_Tests) *100.0 ));
  1119.   if(Ray_Quadric_Tests)
  1120.     fprintf (stat_out,"  Quadric      %10ld  %10ld  %10.2f\n", Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded, ( ((DBL)Ray_Quadric_Tests_Succeeded/(DBL)Ray_Quadric_Tests) *100.0 ));
  1121.   if(Ray_Blob_Tests)
  1122.     fprintf (stat_out,"  Blob         %10ld  %10ld  %10.2f\n", Ray_Blob_Tests, Ray_Blob_Tests_Succeeded, ( ((DBL)Ray_Blob_Tests_Succeeded/(DBL)Ray_Blob_Tests) *100.0 ));
  1123.   if(Ray_Box_Tests)
  1124.     fprintf (stat_out,"  Box          %10ld  %10ld  %10.2f\n", Ray_Box_Tests, Ray_Box_Tests_Succeeded, ( ((DBL)Ray_Box_Tests_Succeeded/(DBL)Ray_Box_Tests) *100.0 ));
  1125.   if(Ray_Cone_Tests)
  1126.     fprintf (stat_out,"  Cone         %10ld  %10ld  %10.2f\n", Ray_Cone_Tests, Ray_Cone_Tests_Succeeded, ( ((DBL)Ray_Cone_Tests_Succeeded/(DBL)Ray_Cone_Tests) *100.0 ) );
  1127.   if(Ray_Disc_Tests)
  1128.     fprintf (stat_out,"  Disc         %10ld  %10ld  %10.2f\n", Ray_Disc_Tests, Ray_Disc_Tests_Succeeded, ( ((DBL)Ray_Disc_Tests_Succeeded/(DBL)Ray_Disc_Tests) *100.0 ) );
  1129.   if(Ray_Poly_Tests)
  1130.     fprintf (stat_out,"  Quartic\\Poly %10ld  %10ld  %10.2f\n", Ray_Poly_Tests, Ray_Poly_Tests_Succeeded, ( ((DBL)Ray_Poly_Tests_Succeeded/(DBL)Ray_Poly_Tests) *100.0 ));
  1131.   if(Ray_Bicubic_Tests)
  1132.     fprintf (stat_out,"  Bezier Patch %10ld  %10ld  %10.2f\n", Ray_Bicubic_Tests, Ray_Bicubic_Tests_Succeeded, ( ((DBL)Ray_Bicubic_Tests_Succeeded/(DBL)Ray_Bicubic_Tests) *100.0 ));
  1133.   if(Ray_Ht_Field_Tests)
  1134.     fprintf (stat_out,"  Height Fld   %10ld  %10ld  %10.2f\n", Ray_Ht_Field_Tests, Ray_Ht_Field_Tests_Succeeded, ( ((DBL)Ray_Ht_Field_Tests_Succeeded/(DBL)Ray_Ht_Field_Tests) *100.0 ));
  1135.   if(Ray_Ht_Field_Box_Tests)
  1136.     fprintf (stat_out,"  Hght Fld Box %10ld  %10ld  %10.2f\n", Ray_Ht_Field_Box_Tests, Ray_HField_Box_Tests_Succeeded, ( ((DBL)Ray_HField_Box_Tests_Succeeded/(DBL)Ray_Ht_Field_Box_Tests) *100.0 ));
  1137.   if(Bounding_Region_Tests)
  1138.     fprintf (stat_out,"  Bounds       %10ld  %10ld  %10.2f\n", Bounding_Region_Tests, Bounding_Region_Tests_Succeeded, ( ((DBL)Bounding_Region_Tests_Succeeded/(DBL)Bounding_Region_Tests) *100.0 ));
  1139.   if(Clipping_Region_Tests)
  1140.     fprintf (stat_out,"  Clips        %10ld  %10ld  %10.2f\n", Clipping_Region_Tests, Clipping_Region_Tests_Succeeded, ( ((DBL)Clipping_Region_Tests_Succeeded/(DBL)Clipping_Region_Tests) *100.0 ));
  1141. #ifdef DB_CODE
  1142.   /* print some additional info */
  1143.  
  1144.   if(nChecked)
  1145.     fprintf (stat_out,"  Slabs        %10ld  %10ld  %10.2f\n", nChecked, nEnqueued, ( ((DBL)nEnqueued/(DBL)nChecked) *100.0 ));
  1146.   if(Project_Tests)
  1147.     fprintf (stat_out,"  Project      %10ld  %10ld  %10.2f\n", Project_Tests, Project_Tests_Succeeded, ( ((DBL)Project_Tests_Succeeded/(DBL)Project_Tests) *100.0 ));
  1148. #endif
  1149.  
  1150.   if(Calls_To_Noise)
  1151.  
  1152.     fprintf (stat_out,"  Calls to Noise:   %10ld\n", Calls_To_Noise);
  1153.   if(Calls_To_DNoise)
  1154.     fprintf (stat_out,"  Calls to DNoise:  %10ld\n", Calls_To_DNoise);
  1155.   if(Shadow_Ray_Tests)
  1156.     fprintf (stat_out,"  Shadow Ray Tests: %10ld     Blocking Objects Found:  %10ld\n",
  1157.       Shadow_Ray_Tests, Shadow_Rays_Succeeded);
  1158.   if(Reflected_Rays_Traced)
  1159.     fprintf (stat_out,"  Reflected Rays:   %10ld\n", Reflected_Rays_Traced);
  1160.   if(Refracted_Rays_Traced)
  1161.     fprintf (stat_out,"  Refracted Rays:   %10ld\n", Refracted_Rays_Traced);
  1162.   if(Transmitted_Rays_Traced)
  1163.     fprintf (stat_out,"  Transmitted Rays: %10ld\n", Transmitted_Rays_Traced);
  1164.   if(Istack_overflows)
  1165.     fprintf (stat_out,"  I-Stack overflows:%10ld\n", Istack_overflows);
  1166.  
  1167.   if(tused==0)
  1168.     {
  1169.     STOP_TIME                  /* Get trace done time. */
  1170.     tused = TIME_ELAPSED       /* Calc. elapsed time. Define TIME_ELAPSED as */
  1171.     /* 0 in your specific CONFIG.H if unsupported */
  1172.     }
  1173.   if (tused != 0)
  1174.     {
  1175.     /* Convert seconds to hours, min & sec. CdW */
  1176.     hours = (long) tused/3600;
  1177.     min = (long) (tused - hours*3600)/60;
  1178.     sec = tused - (DBL) (hours*3600 + min*60);
  1179. #ifdef DB_CODE
  1180.     /* I want the total tracing time in secondes */
  1181.  
  1182.     fprintf (stat_out,"  Time For Trace:   %2ld hours %2ld minutes %4.2f seconds (%.2f sec)\n", hours,min,sec,tused);
  1183. #else
  1184.     fprintf (stat_out,"  Time For Trace:   %2ld hours %2ld minutes %4.2f seconds\n", hours,min,sec);
  1185. #endif
  1186.     }
  1187.   if (Options & VERBOSE_FILE)
  1188.     fclose(stat_out);
  1189.  
  1190.   }
  1191.  
  1192. /* Find a file in the search path. */
  1193.  
  1194. FILE *Locate_File (filename, mode)
  1195. char *filename, *mode;
  1196.   {
  1197.   FILE *f;
  1198.   int i;
  1199.   char pathname[FILE_NAME_LENGTH];
  1200.  
  1201.   /* Check the current directory first. */
  1202.   if ((f = fopen (filename, mode)) != NULL)
  1203.     return (f);
  1204.  
  1205.   for (i = 0 ; i < Library_Path_Index ; i++) 
  1206.     {
  1207.     strcpy (pathname, Library_Paths[i]);
  1208.     if (FILENAME_SEPARATOR != NULL)
  1209.       strcat (pathname, FILENAME_SEPARATOR);
  1210.     strcat (pathname, filename);
  1211.     if ((f = fopen (pathname, mode)) != NULL)
  1212.       return (f);
  1213.     }
  1214.  
  1215.   return (NULL);
  1216.   }
  1217. void print_credits()
  1218.   {
  1219.   fprintf (stderr,"\n");
  1220.   fprintf (stderr,"  Persistence of Vision Raytracer Ver %s%s\n",POV_RAY_VERSION,COMPILER_VER);
  1221.   fprintf (stderr,"    %s\n",DISTRIBUTION_MESSAGE_1);
  1222.   fprintf (stderr,"     %s\n",DISTRIBUTION_MESSAGE_2);
  1223.   fprintf (stderr,"     %s\n",DISTRIBUTION_MESSAGE_3);
  1224.   fprintf (stderr,"  Copyright 1993 POV-Team\n");
  1225.   fprintf (stderr,"  ----------------------------------------------------------------------\n");
  1226.   fprintf (stderr,"  POV-Ray is based on DKBTrace 2.12 by David K. Buck & Aaron A. Collins.\n");
  1227.   fprintf (stderr,"    Contributing Authors: (Alphabetically)\n");
  1228.   fprintf (stderr,"       Steve Anger        Steve A. Bennett   David K. Buck\n");
  1229.   fprintf (stderr,"       Aaron A. Collins   Alexander Enzmann  Dan Farmer\n");
  1230.   fprintf (stderr,"       Douglas Muir       Bill Pulver        Robert Skinner\n");
  1231.   fprintf (stderr,"       Scott Taylor       Drew Wells         Chris Young\n");
  1232.   fprintf (stderr,"    Other contributors listed in the documentation.\n");
  1233.   fprintf (stderr,"  ----------------------------------------------------------------------\n");
  1234.   }
  1235.